package org.shiro.demo.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.shiro.demo.dao.util.Pagination;
import org.shiro.demo.dao.util.QueryCondition;
import org.shiro.demo.entity.Administrator;
import org.shiro.demo.entity.Group;
import org.shiro.demo.entity.GroupInstance;
import org.shiro.demo.entity.GroupOrder;
import org.shiro.demo.entity.OrderBuffer;
import org.shiro.demo.entity.OrderProp;
import org.shiro.demo.entity.ResponseResult;
import org.shiro.demo.entity.User;
import org.shiro.demo.service.IBaseService;
import org.shiro.demo.service.IGroupOrderService;
import org.shiro.demo.service.IOrderBufferService;
import org.shiro.demo.service.IProductService;
import org.shiro.demo.service.IUserService;
import org.shiro.demo.util.UUIDCreator;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/gorder")
public class GroupOrderController {

	@Resource(name = "baseService")
	private IBaseService baseService;
	@Resource
	private IUserService userService;

	@Resource
	private IProductService productService;

	@Resource(name = "groupOrderService")
	private IGroupOrderService groupOrderService;

	private User getCurrentUser() {
		Subject currentAdmin = SecurityUtils.getSubject();
		return (User) currentAdmin.getPrincipal();
	}

	private Administrator getCurrentAdmin() {
		Subject currentAdmin = SecurityUtils.getSubject();
		return (Administrator) currentAdmin.getPrincipal();
	}

	/**
	 * 下单 对应的product的货存量要减一。
	 * 
	 * 开团吧的uuid 前缀。 g
	 * 
	 * 代金券的uuid 前缀 。t
	 * 
	 * 正订单的uuid 前缀。 o
	 *
	 * @param description
	 *            下单备注
	 * 
	 * 
	 */
	@RequestMapping(value = "/add")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public ResponseResult add(HttpSession session, String payType, String deliveryType, int storeId, long groupId, int bufferInterval) {
		ResponseResult rr = new ResponseResult();
		rr.setCode(0);
		rr.setObject("");
		// 查看 group 是否没货了。
		Group group = baseService.getById(Group.class, groupId);
		if (group.getStatus() != true || group.getBalance() - 1 < 0) {
			rr.setInfo("团未激活，或者 余货没了");
			return rr;
		}

		User customer = getCurrentUser();
		// 判断这人是否已经下过单子了。
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("user", QueryCondition.EQ, customer));
		queryConditions.add(new QueryCondition("group", QueryCondition.EQ, group));
		queryConditions.add(new QueryCondition("historyVersion", QueryCondition.EQ, group.getVersion()));
		GroupOrder oldGroupOrder = (GroupOrder) baseService.getSingleResult(GroupOrder.class, queryConditions);

		// 判断 订单存在。
		if (oldGroupOrder != null) {
			if (oldGroupOrder.getOrderProp().getId() == 1) {
				rr.setCode(1);
				// 更新订单信息。
				oldGroupOrder.setPayType(payType);
				oldGroupOrder.setDeliveryType(deliveryType);
				oldGroupOrder.setStoreId(storeId);
				baseService.update(oldGroupOrder);
				rr.setObject(oldGroupOrder);
				rr.setInfo("订单存在，请付款");
				return rr;
			} else if (oldGroupOrder.getOrderProp().getId() == 2L || oldGroupOrder.getOrderProp().getId() == 3L) {
				rr.setCode(0);
				rr.setObject(oldGroupOrder);
				rr.setInfo("订单已存在，你已经购买了此团购");
				return rr;
			}

		}

		// 订单不存在，生成新的订单、
		GroupOrder order = new GroupOrder();
		// 描述=>备注
		order.setDescription("开团");
		order.setUser(customer);
		// 下单时间即为此时此刻
		order.setPostTime(new Date());
		// 交易时间/付款时间此时未定
		order.setDealTime(null);
		// order.setIsSure(false);
		order.setIsPay(false);// 默认未支付
		order.setIsBuffet(true);// 默认是自提
		order.setIsCancel(false);// 默认订单不是取消状态
		order.setBufferInterval(bufferInterval);
		order.setGroup(group);
		order.setHistoryVersion(group.getVersion());
		try {
			System.out.print("---");

			double money = group.getPersonPrice();
			// group的存量要减一 <==> 对应的撤销，要加回去
			// group.setBalance(group.getBalance() - 1);
			// 设置订单的初始状态
			OrderProp orderProp = new OrderProp();
			orderProp.setId(1L);
			orderProp.setStatus(1);
			order.setOrderProp(orderProp);
			// 设置uuid。。g开头+8位uuid+个人id
			order.setUuid("g" + UUIDCreator.getShortUuid() + customer.getId());
			order.setMoney(money);
			// 设置支付方式
			order.setPayType(payType);
			order.setDeliveryType("自提");
			order.setStoreId(storeId);

			// 事务 更新订单 跟 货存
			groupOrderService.addGrouOrderWithMinusAmount(order);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0, "下单失败,订单信息有误.", null);
		}
		return new ResponseResult(1, "下单成功", order);
	}

	/**
	 * 下单 对应的product的货存量要减一。
	 * 
	 * 开团吧的uuid 前缀。 g
	 * 
	 * 代金券的uuid 前缀 。t
	 * 
	 * 正订单的uuid 前缀。 o
	 *
	 * @param description
	 *            下单备注
	 * 
	 * 
	 */
	@RequestMapping(value = "/attend")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public ResponseResult attend(HttpSession session, String payType, String deliveryType, int storeId, int bufferInterval, long grouInstanceId) {
		ResponseResult rr = new ResponseResult();
		rr.setCode(0);
		rr.setObject("");
		// 查看 group 是否没货了。
		GroupInstance groupInstance = baseService.getById(GroupInstance.class, grouInstanceId);
		Group group = groupInstance.getGroup();
		if (group.getStatus() != true || group.getBalance() - 1 < 0) {
			rr.setInfo("余货没了");
			return rr;
		}
		// 唯一与上个函数不一致的地方
		int amount = groupInstance.getOrders().size();
		for (GroupOrder go : groupInstance.getOrders()) {
			if (go.getOrderProp().getId() == 1 || go.getOrderProp().getId() == 4) {
				// 减少那些没付款或者取消的的订单。
				amount--;// amount减少1
			}
		}
		if (group.getPersonAmount() - amount <= 0) {
			rr.setInfo("团满员了");
			return rr;
		}

		User customer = getCurrentUser();
		// 判断这人是否已经下过单子了。
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("user", QueryCondition.EQ, customer));
		queryConditions.add(new QueryCondition("group", QueryCondition.EQ, group));
		queryConditions.add(new QueryCondition("historyVersion", QueryCondition.EQ, group.getVersion()));
		GroupOrder oldGroupOrder = (GroupOrder) baseService.getSingleResult(GroupOrder.class, queryConditions);

		// 判断 订单存在。
		if (oldGroupOrder != null) {
			if (oldGroupOrder.getOrderProp().getId() == 1L) {
				rr.setCode(1);
				rr.setObject(oldGroupOrder);
				oldGroupOrder.setPayType(payType);
				oldGroupOrder.setDeliveryType(deliveryType);
				oldGroupOrder.setStoreId(storeId);
				baseService.update(oldGroupOrder);
				rr.setObject(oldGroupOrder);
				rr.setInfo("订单已存在，未付款");
				return rr;
			} else if (oldGroupOrder.getOrderProp().getId() == 2L || oldGroupOrder.getOrderProp().getId() == 3L) {
				rr.setCode(0);
				rr.setObject(oldGroupOrder);
				rr.setInfo("订单已存在，你已经购买了此团购");
				return rr;
			}
		}

		// 订单不存在，生成新的订单、
		GroupOrder order = new GroupOrder();
		// 描述=>备注
		order.setDescription("参团");
		order.setUser(customer);
		// 下单时间即为此时此刻
		order.setPostTime(new Date());
		// 交易时间/付款时间此时未定
		order.setDealTime(null);
		// order.setIsSure(false);
		order.setIsPay(false);// 默认未支付
		order.setIsBuffet(true);// 默认是自提
		order.setIsCancel(false);// 默认订单不是取消状态
		order.setGroup(group);
		order.setGroupInstance(groupInstance);// 已经进来了，但是没给钱。
		order.setBufferInterval(bufferInterval);
		order.setHistoryVersion(group.getVersion());
		try {
			System.out.print("---");

			double money = group.getPersonPrice();
			// group的存量要减一 <==> 对应的撤销，要加回去
			// group.setBalance(group.getBalance() - 1);
			// 设置订单的初始状态
			OrderProp orderProp = new OrderProp();
			orderProp.setId(1L);
			orderProp.setStatus(1);
			order.setOrderProp(orderProp);
			// 设置uuid。。8位uuid+个人id
			order.setUuid("g" + UUIDCreator.getShortUuid() + customer.getId());
			order.setMoney(money);
			// 设置支付方式
			order.setPayType(payType);
			order.setDeliveryType("自提");

			// 事务 更新订单 跟 货存
			groupOrderService.addGrouOrderWithMinusAmount(order);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0, "下单失败,订单信息有误.", null);
		}
		return new ResponseResult(1, "下单成功", order);
	}

	/**
	 * 根据订单的id获取订单的信息
	 * 
	 * @param id
	 *            订单id
	 * @return ResponseResult,object为order
	 */
	@RequestMapping(value = "/findById")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public ResponseResult findById(@RequestParam(value = "id") Long id) {
		ResponseResult rr = new ResponseResult();

		GroupOrder order = baseService.getById(GroupOrder.class, id);

		User user = getCurrentUser();

		if (user.getId() != order.getUser().getId()) {
			rr.setCode(0);
			rr.setInfo("该订单不属于你");
			return rr;
		}
		rr.setCode(1);
		rr.setInfo("success");
		rr.setObject(order);
		return rr;
	}

	@RequestMapping(value = "/findByUuid")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public Object findByUuid(@RequestParam(value = "uuid") String uuid) {
		ResponseResult rr = new ResponseResult();
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		GroupOrder order = (GroupOrder) baseService.getSingleResult(GroupOrder.class, queryConditions);

		User user = getCurrentUser();
		if (user.getId() != order.getUser().getId()) {
			rr.setCode(0);
			rr.setInfo("该订单不属于你");
			return rr;
		}
		rr.setCode(1);
		rr.setInfo("success");
		rr.setObject(order);
		return rr;
	}

	/**
	 * 获取某个用户的团购券。团购券按照添加团购券的逆序,即越晚提交订单越前
	 * 
	 * @param userId
	 * @param propId
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/get")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public Object get(long propId, int currentPage, int pageSize) {
		if (propId < 1 || propId > 4) {
			return new ResponseResult(0, "状态错误", null);
		}
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();

		User user = getCurrentUser();
		queryConditions.add(new QueryCondition("user", QueryCondition.EQ, user));
		OrderProp prop = new OrderProp();
		prop.setId(propId);
		queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, prop));

		Pagination<GroupOrder> pagination = baseService.getPagination(GroupOrder.class, queryConditions, "ORDER　BY o.postTime desc", currentPage, pageSize);
		for (GroupOrder go : pagination.getRecordList()) {
			// go.setGroup(go.getGroup());// 我们手动调用getGroup来调用,不然死循环

			go.setGroupInstance(go.getGroupInstance()); // 我们手动调用getGroup来调用
		}
		return new ResponseResult(1, "获取用户 " + user.getPhone() + " 的 团购券成功", pagination);
	}

	/**
	 * 店长查询 团购券
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/getGroupOrder")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value = "manager")
	public Object getTicketOrder(@RequestParam(value = "uuid") String uuid) {
		ResponseResult rr = new ResponseResult();

		if (StringUtils.isEmpty(uuid)) {
			rr.setCode(0);
			rr.setInfo("订单号不能为空");
			return rr;
		}

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));

		GroupOrder groupOrder = (GroupOrder) baseService.getSingleResult(GroupOrder.class, queryConditions);

		if (groupOrder == null) {
			rr.setCode(0);
			rr.setInfo("无此订单");
			return rr;
		}
		if (groupOrder.getOrderProp().getId() == 2L) {
			rr.setCode(1);
			rr.setInfo("success");
			rr.setObject(groupOrder);
			return rr;
		}
		rr.setCode(0);
		rr.setInfo("请确认该订单未被提走");
		return rr;
	}

	@Resource(name = "orderBufferService")
	private IOrderBufferService orderBufferService;
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	/**
	 * 店长===》开团吧券 提取
	 * 
	 * @param uuid
	 * @return
	 */
	@RequestMapping(value = "/sureGroupOrder")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value = "manager")
	public Object diliveryTicket(@RequestParam(value = "uuid") String uuid) {
		ResponseResult rr = new ResponseResult();

		if (StringUtils.isEmpty(uuid)) {
			rr.setCode(0);
			return rr;
		}

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		GroupOrder groupOrder = (GroupOrder) baseService.getSingleResult(GroupOrder.class, queryConditions);

		if (groupOrder == null) {
			rr.setCode(0);
			rr.setInfo("团购券不存在");
			return rr;
		}

		if (groupOrder.getOrderProp().getId() != 2L) {
			rr.setCode(0);
			rr.setInfo("团购券不需要被提货");
			return rr;
		}
		Date bufferTime = new Date();
		OrderProp orderProp = baseService.getById(OrderProp.class, 3L);
		groupOrder.setOrderProp(orderProp);
		/** 设置 店长 */
		Administrator admin = getCurrentAdmin();

		groupOrder.setOperator(admin.getPhone());
		groupOrder.setBufferTime(bufferTime);
		try {
			baseService.update(groupOrder);

			// 增加提货信息
			OrderBuffer ob = new OrderBuffer();
			ob.setBufferTime(bufferTime);
			ob.setOperator(admin.getPhone());
			ob.setOrderType(2);// 开团2
			ob.setUuid(uuid);
			ob.setBufferDate(bufferTime);
			ob.setMoney(groupOrder.getMoney());
			ob.setStoreId(groupOrder.getStoreId());// 门店 不做准
			orderBufferService.saveAndCache(admin.getPhone(), sdf.format(bufferTime), ob);// 保存提货信息，，用于后期
																							// 财务报表
		} catch (Exception e) {
			e.printStackTrace();
			rr.setCode(0);
			return rr;
		}
		rr.setCode(1);
		rr.setInfo("success");
		rr.setObject(null);
		return rr;
	}

	/**
	 * 店长查询自己处理过的订单
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getHandledGroupOrder")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value = "manager")
	public Object getHandledGroupOrder(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "pageNumber") Integer pageNumber, @RequestParam(value = "orderBy", required = false) String orderBy, @RequestParam(value = "asc", required = false) Boolean asc) {

		Administrator admin = getCurrentAdmin();

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("operator", QueryCondition.EQ, admin.getPhone()));

		Pagination<GroupOrder> pagination = null;

		if (orderBy != null && asc != null) {
			pagination = baseService.getPagination(GroupOrder.class, queryConditions, " order by o." + orderBy + " " + (asc ? " ASC " : " DESC "), pageNumber, pageSize);
		} else {
			pagination = baseService.getPagination(GroupOrder.class, queryConditions, "ORDER BY o.postTime DESC", pageNumber, pageSize);
		}

		return pagination;
	}

	@RequestMapping(value = "/adminGetGroupOrders")
	@RequiresAuthentication
	@RequiresRoles("super-administrator")
	public @ResponseBody Object adminGetGroupOrders(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "pageNumber") Integer pageNumber, @RequestParam(value = "orderBy", required = false) String orderBy, @RequestParam(value = "asc", required = false) Boolean asc, @RequestParam(value = "propId") long propId) {

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		OrderProp orderProp = baseService.getById(OrderProp.class, propId);
		queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, orderProp));

		Pagination<GroupOrder> pagination = null;
		if (orderBy != null && asc != null) {
			pagination = baseService.getPagination(GroupOrder.class, queryConditions, " order by o." + orderBy + " " + (asc ? " ASC " : " DESC "), pageNumber, pageSize);
		} else {
			pagination = baseService.getPagination(GroupOrder.class, queryConditions, null, pageNumber, pageSize);
		}
		return pagination;
	}

	/**
	 * 根据订单的id删除订单
	 * 
	 * @param orderId
	 *            订单id
	 * @return ResponseResult
	 */
	@RequestMapping(value = "/cancelOrder")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("customer")
	public ResponseResult cancelOrder(Long orderId) {
		// 检查订单 是不是这个顾客的。
		ResponseResult rr = new ResponseResult();
		User user = getCurrentUser();
		try {

			GroupOrder order = baseService.getById(GroupOrder.class, orderId);
			if (!order.getUser().getPhone().equals(user.getPhone())) {
				rr.setInfo("订单不属于您");
				rr.setCode(0);
				return rr;
			}

			// 取消订单
			OrderProp orderProp = new OrderProp();
			orderProp.setId(4L);
			orderProp.setStatus(4);
			order.setOrderProp(orderProp);

			baseService.update(order);

		} catch (Exception e) {
			e.printStackTrace();
			rr.setCode(0);
			return rr;
		}
		rr.setCode(1);
		rr.setInfo("success");
		rr.setObject(null);
		return rr;
	}

}
